﻿using System;
using System.Threading.Tasks;
using NationalD3.Domain.Base;
using MediatR;
using System.Collections.Concurrent;
using NationalD3.Domain.Events;

namespace NationalD3.Infrastructure.Bus
{
    /// <summary>
    /// 内存消息总线实现类
    /// </summary>
    public class InMemoryBus : IEventBus
    {
        //构造函数注入
        private readonly IMediator _mediator;
        //注入服务工厂
        //private readonly ServiceFactory _serviceFactory;
        //private static readonly ConcurrentDictionary<Type, object> _requestHandlers = new ConcurrentDictionary<Type, object>();
        // 事件仓储服务
        private readonly IEventStoreService _eventStoreService;


        public InMemoryBus(IMediator mediator, IEventStoreService eventStoreService)
        {
            _mediator = mediator;
            //_serviceFactory = serviceFactory;
            _eventStoreService = eventStoreService;
        }

        /// <summary>
        /// 引发事件的实现方法
        /// </summary>
        /// <typeparam name="T">泛型 继承 Event：INotification</typeparam>
        /// <param name="event">事件模型，比如StudentRegisteredEvent</param>
        /// <returns></returns>
        public Task RaiseEvent<T>(T @event) where T : Event
        {
            // 除了领域通知以外的事件都保存下来
            if (!@event.MessageType.Equals("DomainNotification"))
                _eventStoreService?.Save(@event);

            // MediatR中介者模式中的第二种方法，发布/订阅模式
            return _mediator?.Publish(@event);
        }

        /// <summary>
        /// 实现接口方法，该方法无返回值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="command"></param>
        /// <returns></returns>
        public Task SendCommand<T>(T command) where T : Command
        {
            // MediatR中介者模式中的第一种方法，请求/响应模式
            return _mediator?.Send(command);  
        }
    }
}
